<script setup>
import { ref, watch, onMounted, computed } from "vue";
import Sortable from "sortablejs";
import tool from "@/utils/tool";
import { message } from "@/utils/message";

const props = defineProps({
  modelValue: [String, Number, Array],
  maxLength: {
    type: [String, Number],
    default: 1,
    validator: (val) => Number(val) >= 0,
  },
  disabled:{
    type:Boolean,
    default:false
  },
  help: {
    type: String,
    default: "",
  },
});

const emit = defineEmits(["update:modelValue"]);

const fileList = ref([]);
const attachList = ref([]);
const pickerRef = ref(null);
const sortableList = ref(null);

const maxLengthNum = computed(() => Number(props.maxLength));

const isDisabled = computed(() => props.disabled);

const helpText = computed(() => {
  if (props.help) return props.help;
  return `建议尺寸：800*800，可拖拽改变图片顺序，默认首张图为主图，最多上传${maxLengthNum.value}张`;
});

const openPicker = () => {
  pickerRef.value?.open();
};

const getFiles = (list) => {
  if (!list || (Array.isArray(list) && list.length === 0)) {
    message("未选择任何图片", { type: "warning" });
    return;
  }
  pickerRef.value.close();
  fileList.value = Array.isArray(list) ? list : [list];
  attachList.value = fileList.value.map((item) => item.att_dir).filter(Boolean);
  updateModelValue();
};

const handleRemove = (index) => {
  attachList.value.splice(index, 1);
  fileList.value.splice(index, 1);
  updateModelValue();
};

const updateModelValue = () => {
  if (maxLengthNum.value === 1) {
    emit("update:modelValue", attachList.value.length ? attachList.value[0] : null);
  } else {
    emit("update:modelValue", [...attachList.value]);
  }
};

watch(
  () => props.modelValue,
  (newVal) => {
    if (Array.isArray(newVal)) {
      attachList.value = [...newVal];
    } else if (newVal) {
      attachList.value = [newVal];
    } else {
      attachList.value = [];
    }
    // 同步 fileList
    fileList.value = attachList.value.map((path, index) => ({
      att_dir: path,
      attr_id: `temp-${index}`,
    }));
  },
  { immediate: true }
);

onMounted(() => {
  if (!sortableList.value) return;
  Sortable.create(sortableList.value, {
    animation: 150,
    handle: ".wd-drag-handle",
    draggable: ".wd-pre-img-item",
    ghostClass: "sortable-ghost",
    onEnd(evt) {
      const movedItem = attachList.value.splice(evt.oldIndex, 1)[0];
      attachList.value.splice(evt.newIndex, 0, movedItem);
      const movedFile = fileList.value.splice(evt.oldIndex, 1)[0];
      fileList.value.splice(evt.newIndex, 0, movedFile);
      updateModelValue();
    },
  });
});
</script>

<template>
  <div class="wd-upload-image flex flex-col">
    <div class="wd-pre-img-list no-select" ref="sortableList">
      <div
        v-for="(item, index) in attachList"
        :key="item + '-' + index"
        class="wd-pre-img-item"
      >
        <el-image :src="tool.attachUrl(item)" fit="cover" />
        <div class="wd-preview">
          <icon
            icon="vi-tdesign:drag-move"
            v-if="maxLengthNum > 1"
            class="wd-drag-handle"
          ></icon>
          <icon
            icon="vi-tdesign:delete"
            @click="handleRemove(index)"
          ></icon>
        </div>
      </div>

      <div
        v-if="attachList.length < maxLengthNum && !isDisabled"
        class="upload-picker"
        @click="openPicker"
      >
        <i class="el-icon-picture-outline" style="font-size: 24px"></i>
        <icon icon="vi-tdesign:add" color="#0baf4d" :size="24" />
      </div>
    </div>
    <div class="wd-picker-tips">{{ helpText }}</div>
    <image-picker
      ref="pickerRef"
      @getPickerFiles="getFiles"
      :maxLength="maxLengthNum"
    />
  </div>
</template>

<style lang="less" scoped>
.upload-picker {
  width: 68px;
  height: 68px;
  border: 1px dashed #0baf4d;
  display: flex;
  justify-content: center;
  align-items: center;
  background: #f6fdff;
  cursor: pointer;
  transition: border-color 0.2s;
  &:hover {
    border-color: #0b8f3d;
  }
}

.wd-picker-tips {
  color: #999999;
  font-size: 12px;
  margin-top: 5px;
}

.wd-pre-img-list {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
}

.wd-pre-img-item {
  width: 70px;
  height: 70px;
  margin: 5px;
  position: relative;
  border: 1px solid #d1d1d1;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;

  .el-image {
    width: 100%;
    height: 100%;
    object-fit: cover;
  }

  .wd-preview {
    position: absolute;
    width: 100%;
    height: 30%;
    left: 0;
    bottom: -100%;
    background: rgba(0, 0, 0, 0.5);
    z-index: 1000;
    display: flex;
    justify-content: space-around;
    align-items: center;
    color: #fff;
    transition: bottom 0.2s;
    .wd-icon {
      font-size: 12px;
      cursor: pointer;
    }
  }

  &:hover {
    .wd-preview {
      bottom: 0;
    }
  }

  &.sortable-ghost {
    opacity: 0.5;
    background: #f0f0f0;
  }
}
</style>
